home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / MNetsrc.hqx / Mac TCP_IP Source v.33 / nr4user.c < prev    next >
Text File  |  1989-01-13  |  5KB  |  214 lines

  1. /* net/rom level 4 (transport) protocol user level calls
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "nr4.h"
  14. #include <ctype.h>
  15.  
  16. #undef NR4DEBUG
  17.  
  18. /* Open a NET/ROM transport connection */
  19. struct nr4cb *
  20. open_nr4(node,user,r_upcall,t_upcall,s_upcall,puser)
  21. struct ax25_addr *node ;    /* destination node address */
  22. struct ax25_addr *user ;    /* local ax25 user callsign */
  23. void (*r_upcall)() ;        /* received data upcall */
  24. void (*t_upcall)() ;        /* transmit upcall */
  25. void (*s_upcall)() ;        /* state change upcall */
  26. char *puser ;                /* pointer to upper level control block */
  27. {
  28.     struct nr4cb *cb ;
  29.     struct nr4hdr hdr ;
  30.  
  31.     if ((cb = new_n4circ()) == NULLNR4CB)
  32.         return NULLNR4CB ;        /* No circuits available */
  33.  
  34.     /* Stuff what info we can into control block */
  35.  
  36.     cb->user = *node ;        /* When we initiate, user is remote node */
  37.     cb->node = *node ;
  38.     cb->luser = *user ;        /* Save local user for connect retries */
  39.     cb->r_upcall = r_upcall ;
  40.     cb->t_upcall = t_upcall ;
  41.     cb->s_upcall = s_upcall ;
  42.     cb->puser = puser ;
  43.  
  44.     /* Format connect request header */
  45.  
  46.     hdr.opcode = NR4OPCONRQ ;
  47.     hdr.u.conreq.myindex = cb->mynum ;
  48.     hdr.u.conreq.myid = cb->myid ;
  49.     hdr.u.conreq.window = Nr4window ;
  50.     hdr.u.conreq.user = *user ;
  51.  
  52.     /* The choice of mycall here is suspect.  If I have a unique */
  53.     /* callsign per interface, then a layer violation will be */
  54.     /* required to determine the "real" callsign for my (virtual) */
  55.     /* node.  This suggests that callsign-per-interface is not */
  56.     /* desirable, which answers *that* particular open question. */
  57.     
  58.     hdr.u.conreq.node = mycall ;
  59.  
  60.     /* Set and start connection retry timer */
  61.  
  62.     cb->cdtries = 1 ;
  63.     cb->srtt = Nr4irtt ;
  64.     cb->tcd.start = (2 * cb->srtt) / MSPTICK ;
  65.     cb->tcd.func = nr4cdtimeout ;
  66.     cb->tcd.arg = (char *)cb ;
  67.     start_timer(&cb->tcd) ;
  68.     
  69.     /* Send connect request packet */
  70.  
  71.     nr4sframe(node, &hdr, NULLBUF) ;
  72.  
  73.     /* Set up initial state and signal state change */
  74.  
  75.     cb->state = NR4STDISC ;
  76.     nr4state(cb, NR4STCPEND) ;
  77.  
  78.     /* Return control block address */
  79.  
  80.     return cb ;
  81. }
  82.  
  83. /* Send a net/rom transport data packet */
  84. int
  85. send_nr4(cb,bp)
  86. struct nr4cb *cb ;
  87. struct mbuf *bp ;
  88. {
  89.     if (cb == NULLNR4CB || bp == NULLBUF)
  90.         return -1 ;
  91.     enqueue(&cb->txq,bp) ;
  92.     return nr4output(cb) ;
  93. }
  94.  
  95. /* Receive incoming net/rom transport data */
  96. struct mbuf *
  97. recv_nr4(cb,cnt)
  98. struct nr4cb *cb ;
  99. int16 cnt ;
  100. {
  101.     struct mbuf *bp ;
  102.  
  103.     if (cb->rxq == NULLBUF)
  104.         return NULLBUF ;
  105.  
  106.     bp = cb->rxq ;            /* Just give `em everything */
  107.     cb->rxq = NULLBUF ;
  108.  
  109.     /* Since we took everything, we always go unchoked.  If we */
  110.     /* ever change this code to use cnt, or make it a real packet */
  111.     /* delivery, there will have to be a check to see if the queue */
  112.     /* has gotten short enough yet. */
  113.  
  114.     if (cb->qfull) {
  115.         cb->qfull = 0 ;                /* Choke flag off */
  116.         nr4ackit((char *)cb) ;        /* Get things rolling again */
  117.     }
  118.  
  119.     return bp ;
  120. }
  121.  
  122. /* Close a NET/ROM connection */
  123. void
  124. disc_nr4(cb)
  125. struct nr4cb *cb ;
  126. {
  127.     struct nr4hdr hdr ;
  128.     int i ;
  129.     
  130.     if (cb->state != NR4STCON)
  131.         return ;
  132.  
  133.     stop_timer(&cb->tchoke) ;
  134.     
  135.     /* Clear out the transmit queue and window */
  136.  
  137.     free_q(&cb->txq) ;
  138.  
  139.     for (i = 0 ; i < cb->window ; i++) {
  140.         free_mbuf(cb->txbufs[i].data) ;
  141.         cb->txbufs[i].data = NULLBUF ;
  142.         stop_timer(cb->txbufs[i].tretry) ;
  143.     }
  144.  
  145.     /* Format disconnect request packet */
  146.     
  147.     hdr.opcode = NR4OPDISRQ ;
  148.     hdr.yourindex = cb->yournum ;
  149.     hdr.yourid = cb->yourid ;
  150.  
  151.     /* Set and start timer */
  152.     
  153.     cb->cdtries = 1 ;
  154.     cb->tcd.start = (2 * cb->srtt) / MSPTICK ;
  155.     cb->tcd.func = nr4cdtimeout ;
  156.     cb->tcd.arg = (char *)cb ;
  157.     start_timer(&cb->tcd) ;
  158.  
  159.     /* Send packet */
  160.  
  161.     nr4sframe(&cb->node, &hdr, NULLBUF) ;
  162.  
  163.     /* Signal state change */
  164.  
  165.     nr4state(cb, NR4STDPEND) ;
  166.     
  167. }
  168.  
  169. /* Abruptly terminate a NET/ROM transport connection */
  170. void
  171. reset_nr4(cb)
  172. struct nr4cb *cb ;
  173. {
  174.     cb->dreason = NR4RRESET ;
  175.     nr4state(cb,NR4STDISC) ;
  176. }
  177.  
  178.  
  179. /* Force retransmission on a NET/ROM transport connection */
  180. int
  181. kick_nr4(cb)
  182. struct nr4cb *cb ;
  183. {
  184.     unsigned seq ;
  185.     struct timer *t ;
  186.  
  187.     if(!nr4valcb(cb))
  188.         return -1 ;
  189.  
  190.     switch (cb->state) {
  191.       case NR4STCPEND:
  192.       case NR4STDPEND:
  193.           stop_timer(&cb->tcd) ;
  194.         nr4cdtimeout((char *)cb) ;
  195.         break ;
  196.  
  197.       case NR4STCON:
  198.         if (cb->nextosend != cb->ackxpected) {    /* if send window is open: */
  199.             for (seq = cb->ackxpected ;
  200.                  nr4between(cb->ackxpected, seq, cb->nextosend) ;
  201.                  seq = (seq + 1) & NR4SEQMASK) {
  202.                 t = &cb->txbufs[seq % cb->window].tretry ;
  203.                 stop_timer(t) ;
  204.                 t->state = TIMER_EXPIRE ;    /* fool retry routine */
  205.             }
  206.             nr4txtimeout((char *)cb) ;
  207.         }
  208.         break ;
  209.     }
  210.  
  211.     return 0 ;
  212. }
  213.  
  214.